package net.gdface.service.facedb;

import java.util.List;
import java.util.concurrent.TimeUnit;


import com.facebook.swift.service.ThriftEventHandler;
import com.facebook.swift.service.ThriftServerConfig;
import com.gitee.l0km.xthrift.service.ThriftServerService;

import io.airlift.units.Duration;
import net.gdface.facedb.FaceDb;
import net.gdface.facedb.decorator.FaceDbThriftDecorator;
import net.gdface.service.facedb.spring.RestfulService;

import static com.google.common.base.Preconditions.*;
/**
 * {@link FaceDb}服务封装
 * @author guyadong
 *
 */
public class FacedbService extends ThriftServerService implements FacedbServiceConstants {
	private static FacedbService service;
	private static FacedbService httpService;
	private static final FacedbServiceConfig serviceConfig = FacedbServiceConfig.getInstance();
	private static final FaceDb FACEDB_INSTANCE = serviceConfig.getFaceDb();
	// 封装为thrift服务的faceapi接口静态实例
	private static final FaceDbThriftDecorator FACEAPI_THRIFT_DECORATOR = new FaceDbThriftDecorator(FACEDB_INSTANCE);
	/**
	 * 从配置文件中读取参数创建{@link ThriftServerConfig}实例
	 * @return
	 */
	public static ThriftServerConfig makeThriftServerConfig(){
		ThriftServerConfig thriftServerConfig = new ThriftServerConfig();
		int intValue ;
		thriftServerConfig.setPort(serviceConfig.getServicePort());
		if((intValue  = serviceConfig.getConnectionLimit()) >0){
			thriftServerConfig.setConnectionLimit(intValue);
		}
		if((intValue = serviceConfig.getIdleConnectionTimeout())>0){
			Duration timeout = new Duration(intValue,TimeUnit.SECONDS);
			thriftServerConfig.setIdleConnectionTimeout(timeout);
		}
		if((intValue = serviceConfig.getWorkThreads())>0){
			thriftServerConfig.setWorkerThreads(intValue);
		}
		return thriftServerConfig;
	}
	/**
	 * 创建服务实例(frame,binary)
	 * @return
	 */
	public static synchronized final FacedbService buildService(){
		return service = buildService(service,makeThriftServerConfig());
	}
	/**
	 * 创建HTTP服务实例(http,json)
	 * @return
	 */
	public static synchronized final FacedbService buildHttpService(){
		return httpService = buildService(httpService,
				makeThriftServerConfig()
					.setPort(serviceConfig.getXhrPort())
					.setTransportName(ThriftServerService.HTTP_TRANSPORT)
					.setProtocolName(ThriftServerService.JSON_PROTOCOL));
	}
	/**
	 * 启动RESTful WEB服务实例
	 */
	public static synchronized final void startRestfulService(){
		
		RestfulService.setHttpPort(serviceConfig.getRestfulPort());
		RestfulService.setInterfaceInstance(FACEDB_INSTANCE);
		RestfulService.setSwaggerEnable(serviceConfig.isSwaggerEnable());
		RestfulService.setCorsEnable(serviceConfig.isCorsEnable());
		RestfulService.run();
	}
	/**
	 * 创建服务实例<br>
	 * @param service 服务实例,如果为{@code null}或服务已经停止则创建新的服务实例
	 * @param config thrift服务配置
	 * @return 返回{@code service}或创建的新的服务实例
	 */
	private static FacedbService buildService(FacedbService service,ThriftServerConfig config){
		if(null == service || State.TERMINATED == service.state() || State.FAILED == service.state()){		
			service = ThriftServerService.bulider()
						.withServices(FACEAPI_THRIFT_DECORATOR)	
						.setThriftServerConfig(config)
						.build(FacedbService.class);	
		}
		checkState(State.NEW == service.state(),"INVALID service state %s ",service.toString());
		return service;
	}
	public FacedbService(List<?> services, 
			List<ThriftEventHandler> eventHandlers,
			ThriftServerConfig thriftServerConfig) {
		super(services, eventHandlers, thriftServerConfig);
	}
	/**
	 * @return service
	 */
	public static FacedbService getService() {
		return service;
	}
	/**
	 * @return httpService
	 */
	public static FacedbService getHttpService() {
		return httpService;
	}
}
